package com.boot.admin.modules.sys.ai.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.boot.admin.base.R;
import com.boot.admin.modules.sys.ai.config.QiniuAiConfig;
import com.boot.admin.modules.sys.ai.model.dto.QiniuChatRequest;
import com.boot.admin.modules.sys.ai.model.vo.AiMessageVO;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * AI大模型服务 - 七牛云集成版本
 *
 * @author 李飞洋
 * @date 2025/9/24
 */
@Slf4j
@Service
public class AiLlmService {

    private final QiniuAiConfig qiniuAiConfig;
    private final OkHttpClient httpClient;

    /**
     * 构造HTTP客户端
     */
    public AiLlmService(QiniuAiConfig qiniuAiConfig) {
        this.qiniuAiConfig = qiniuAiConfig;
        this.httpClient = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(qiniuAiConfig.getTimeout(), TimeUnit.SECONDS)
                .readTimeout(qiniuAiConfig.getTimeout(), TimeUnit.SECONDS)
                .build();
    }

    /**
     * 生成AI回复
     */
    public R<String> generateResponse(String systemPrompt, List<AiMessageVO> history, String userInput) {
        try {
            // 构建请求消息列表
            List<ChatMessage> messages = buildMessages(systemPrompt, history, userInput);

            // 构建请求对象
            QiniuChatRequest request = new QiniuChatRequest();
            request.setModel(determineModel());
            request.setMessages(messages);
            request.setStream(false); // 非流式输出
            request.setMaxTokens(qiniuAiConfig.getMaxTokens());
            request.setTemperature(0.7);
            request.setTopP(1.0);

            // 发送请求
            String responseText = sendChatRequest(request);

            // 解析响应
            QiniuChatResponse response = JSONUtil.toBean(responseText, QiniuChatResponse.class);

            // 检查错误
            if (response.getError() != null) {
                log.error("七牛云API返回错误: {}", response.getError().getMessage());
                return R.NG("AI服务调用失败: " + response.getError().getMessage());
            }

            // 提取AI回复内容
            if (response.getChoices() == null || response.getChoices().isEmpty()) {
                log.error("七牛云API响应为空");
                return R.NG("AI服务未返回有效响应");
            }

            String aiContent = response.getChoices().get(0).getMessage().getContent();

            // 记录使用情况
            if (response.getUsage() != null) {
                log.info("七牛云API调用完成 - 输入tokens: {}, 输出tokens: {}, 总计tokens: {}",
                        response.getUsage().getPromptTokens(),
                        response.getUsage().getCompletionTokens(),
                        response.getUsage().getTotalTokens());
            }

            log.info("大模型响应成功: {}", aiContent);
            return R.OK(aiContent);

        } catch (Exception e) {
            log.error("调用七牛云大模型失败", e);
            return R.NG("大模型调用失败: " + e.getMessage());
        }
    }

    /**
     * 构建消息列表
     */
    private List<ChatMessage> buildMessages(String systemPrompt, List<AiMessageVO> history, String userInput) {
        List<ChatMessage> messages = new ArrayList<>();

        // 添加系统提示词
        if (StrUtil.isNotBlank(systemPrompt)) {
            messages.add(new ChatMessage("system", systemPrompt));
        }

        // 添加历史对话记录
        if (history != null && !history.isEmpty()) {
            // 按消息序号排序，确保对话顺序正确
            history.stream()
                    .sorted((m1, m2) -> Integer.compare(m1.getMessageIndex(), m2.getMessageIndex()))
                    .forEach(message -> {
                        if (message.isFromUser()) {
                            messages.add(new ChatMessage("user", message.getContent()));
                        } else if (message.isFromAi()) {
                            messages.add(new ChatMessage("assistant", message.getContent()));
                        }
                    });
        }

        // 添加当前用户输入
        if (StrUtil.isNotBlank(userInput)) {
            messages.add(new ChatMessage("user", userInput));
        }

        return messages;
    }

    /**
     * 发送聊天请求
     */
    private String sendChatRequest(QiniuChatRequest request) throws IOException {
        String requestBody = JSONUtil.toJsonStr(request);
        log.info("发送七牛云API请求: {}", requestBody);

        Request httpRequest = new Request.Builder()
                .url(qiniuAiConfig.getBaseUrl() + "/chat/completions")
                .header("Authorization", "Bearer " + qiniuAiConfig.getApiKey())
                .header("Content-Type", "application/json")
                .post(RequestBody.create(requestBody, MediaType.parse("application/json")))
                .build();

        try (Response response = httpClient.newCall(httpRequest).execute()) {
            if (!response.isSuccessful()) {
                String errorBody = response.body() != null ? response.body().string() : "未知错误";
                log.error("七牛云API请求失败 - HTTP状态码: {}, 响应: {}", response.code(), errorBody);
                throw new IOException("API请求失败: HTTP " + response.code() + " - " + errorBody);
            }

            String responseText = response.body().string();
            log.info("七牛云API响应: {}", responseText);
            return responseText;
        }
    }

    /**
     * 确定使用的模型
     */
    private String determineModel() {
        String model = qiniuAiConfig.getDefaultModel();

        // 如果启用搜索功能，在模型名后添加?search
        if (Boolean.TRUE.equals(qiniuAiConfig.getEnableSearch())) {
            model += "?search";
        }

        return model;
    }

    /**
     * 聊天消息内部类
     */
    @Data
    public static class ChatMessage {
        private String role;
        private String content;

        public ChatMessage() {}

        public ChatMessage(String role, String content) {
            this.role = role;
            this.content = content;
        }
    }

    /**
     * 七牛云聊天响应
     */
    @Data
    public static class QiniuChatResponse {
        private String id;
        private String object;
        private Long created;
        private String model;
        private List<ChatChoice> choices;
        private ChatUsage usage;
        private ChatError error;
    }

    /**
     * 聊天选择
     */
    @Data
    public static class ChatChoice {
        private Integer index;
        private ChatMessage message;

        @JsonProperty("finish_reason")
        private String finishReason;
    }

    /**
     * 使用情况统计
     */
    @Data
    public static class ChatUsage {
        @JsonProperty("prompt_tokens")
        private Integer promptTokens;

        @JsonProperty("completion_tokens")
        private Integer completionTokens;

        @JsonProperty("total_tokens")
        private Integer totalTokens;
    }

    /**
     * 错误信息
     */
    @Data
    public static class ChatError {
        private String code;
        private String message;
        private String type;
    }
}